package flex.cc.order.manage.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.basicinformation.dao.ChannelDataDao;
import flex.cc.basicinformation.dao.ServiceProviderDataDao;
import flex.cc.basicinformation.entity.ServiceProviderDataEntity;
import flex.cc.basicinformation.entity.ServiceProviderEntity;
import flex.cc.basicinformation.service.ChannelService;
import flex.cc.basicinformation.service.ServiceProviderService;
import flex.cc.common.Constants;
import flex.cc.common.utils.DateUtil;
import flex.cc.core.utils.RequestUtil;
import flex.cc.order.manage.dao.OrderCustomerDao;
import flex.cc.order.manage.dao.OrderMainDao;
import flex.cc.order.manage.dao.OrderManageDao;
import flex.cc.order.manage.dao.OrderPolicyDao;
import flex.cc.order.manage.dao.OrderRescueDao;
import flex.cc.order.manage.dao.OrderServiceProviderDao;
import flex.cc.order.manage.dao.OrderServiceRescueDao;
import flex.cc.order.manage.dao.OrderTrackDao;
import flex.cc.order.manage.dto.order.OrderCustomerEntity;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderPolicyEntity;
import flex.cc.order.manage.dto.order.OrderRescueEntity;
import flex.cc.order.manage.dto.order.OrderServiceProviderEntity;
import flex.cc.order.manage.dto.order.OrderServiceRescueEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.model.CancelNoticeModel;
import flex.cc.order.manage.service.CancelNoticeService;
import flex.cc.order.manage.service.OrderManageService;
import flex.cc.system.dao.DictCodeDao;
import flex.cc.system.entity.DictCodeEntity;
import flex.cc.vehicle_svr.service.CancelService;
import flex.cc.vehicle_svr.service.InputService;
import lombok.extern.slf4j.Slf4j;

/**
 * 服务单管理
 */
@Service("orderManageService")
@Slf4j
public class OrderManageServiceImpl implements OrderManageService {
	private static final Logger logger = LoggerFactory.getLogger(OrderManageServiceImpl.class);
	
    @Autowired
    private OrderManageDao orderManageDao;
    @Autowired
    private OrderMainDao orderMainDao;
    @Autowired
    private OrderCustomerDao orderCustomerDao;
    @Autowired
    private OrderPolicyDao orderPolicyDao;
    @Autowired
    private OrderRescueDao orderRescueDao;
    @Autowired
    private OrderTrackDao orderTrackDao;
    @Autowired
    private InputService inputService;
    @Autowired
    private CancelService cancelService;
    @Autowired
    private OrderServiceProviderDao orderServiceProviderDao;
    @Autowired
    private OrderServiceRescueDao orderServiceRescueDao;
    @Value("${pengda.createRescue}")
    private String createRescue;
    @Value("${pengda.cancelRescue}")
    private String cancelRescue;
    @Autowired
    private ServiceProviderDataDao serviceProviderDataDao;
    @Resource
	private ChannelService channelService;
    @Resource
	private ChannelDataDao channelDataDao;
    @Resource
	private DictCodeDao dictCodeDao;
    @Autowired
    private ServiceProviderService serviceProviderService;
    @Autowired
    private CancelNoticeService cancelNoticeService;

    //页面保存提交、手动派单
    /**
   	*
   	* @author WANGCONG
   	* 2021年10月20日下午6:32:08
   	* @param dataId         服务单主键
   	* @param allot_rescue_url 下单地址
   	* @param servicerId     服务商Id
   	* @param publicKey      公钥
   	* @param b              是否验证服务商一致
   	* @desc 手动派单提交
   	*/
    @Override
    public Map<String, Object> allotRescue(String dataId, String allot_rescue_url, String servicerId, String publicKey, boolean b) {
        Map<String, Object> params = new HashMap<>();
        params.put("dataId", dataId);
        Map<String, Object> requestBodyMap = new HashMap<String, Object>();
        OrderMainEntity orderMainEntity = orderMainDao.getOneByParams(params);
        String result = "";
        Boolean flag = true;
        Map<String, Object> resultMap = new HashMap<>();
        if (orderMainEntity != null){
            String status = orderMainEntity.getStatus();
            if ("01".equals(status) || "00".equals(status)){ //00：派单失败
                Map<String, Object> info = new HashMap<>();
                info.put("orderNo", orderMainEntity.getOrderNo());
                OrderCustomerEntity orderCustomerEntity = orderCustomerDao.getOneByParams(info);
                OrderPolicyEntity orderPolicyEntity = orderPolicyDao.getOneByParams(info);
                OrderRescueEntity orderRescueEntity = orderRescueDao.getOneByParams(info);
                OrderTrackEntity orderTrackEntity = orderTrackDao.getOneByParams(info);
                OrderServiceProviderEntity orderServiceProviderEntity = orderServiceProviderDao.getOneByParams(info);
                if(b && servicerId.equals(orderServiceProviderEntity.getServerId())){
                	resultMap.put("dataId", dataId);
                    resultMap.put("result", "服务商一致");
                    resultMap.put("flag", flag);
                    return resultMap;
                }
                if (PublicUtil.isNotEmpty(orderMainEntity)){
                    requestBodyMap.put("orderNo", orderMainEntity.getOrderNo());
                    requestBodyMap.put("ownerOrderNo", orderMainEntity.getOwnerOrderNo());
                    requestBodyMap.put("incidentType", PublicUtil.isNotEmpty(orderMainEntity.getIncidentType()) ? orderMainEntity.getIncidentType() : 0); // 可以取实际值，为空的默认非事故
                    //requestBodyMap.put("incidentType", 0); // TODO 联调默认事故类型为非事故
                    requestBodyMap.put("serviceType", orderMainEntity.getServiceItem());
                }
                if (PublicUtil.isNotEmpty(orderTrackEntity)){
                    requestBodyMap.put("serviceContent", orderTrackEntity.getTrackDesc());
                }
                if (PublicUtil.isNotEmpty(orderCustomerEntity)){
                    requestBodyMap.put("reporterName", orderCustomerEntity.getUsername());
                    requestBodyMap.put("reporterPhone", orderCustomerEntity.getMobile());
                    requestBodyMap.put("reporterIdNo", orderCustomerEntity.getIdCard());
                }
                if(PublicUtil.isNotEmpty(orderPolicyEntity)){
                    requestBodyMap.put("vehicleNo", orderPolicyEntity.getCarNo());
                    requestBodyMap.put("vehicleType", orderPolicyEntity.getCarModel());
                    requestBodyMap.put("vin", orderPolicyEntity.getCarVin());
                }
                if (PublicUtil.isNotEmpty(orderRescueEntity)){
                    requestBodyMap.put("caseProvince", orderRescueEntity.getAddrProvince());
                    requestBodyMap.put("caseCity", orderRescueEntity.getAddrCity());
                    requestBodyMap.put("caseCounty", orderRescueEntity.getAddrCounty());
                    requestBodyMap.put("caseLocation", orderRescueEntity.getAddrAddress());
                    requestBodyMap.put("caseLongitude", orderRescueEntity.getAddrLongitude());
                    requestBodyMap.put("caseLatitude", orderRescueEntity.getAddrLatitude());
                    requestBodyMap.put("desState", orderRescueEntity.getDesProvince());
                    requestBodyMap.put("desCity", orderRescueEntity.getDesCity());
                    requestBodyMap.put("desCounty", orderRescueEntity.getDesCounty());
                    requestBodyMap.put("desAddress", orderRescueEntity.getDesAddress());
                    requestBodyMap.put("desLongitude", orderRescueEntity.getDesLongitude());
                    requestBodyMap.put("desLatitude", orderRescueEntity.getDesLatitude());
                    requestBodyMap.put("dragEnvironment", orderRescueEntity.getEnv());
                }

                //TODO 下单默认成功
                result = inputService.allotRescue(allot_rescue_url, publicKey, requestBodyMap);
                //result = "{\"resultCode\":\"0\",\"message\":\"成功\"}";
                if (result != null) {
                    JSONObject resultObj = JSONObject.parseObject(result);
                    String resultCode = PublicUtil.isNotEmpty(resultObj.get("resultCode")) ? resultObj.get("resultCode").toString() : null; // 0：正常；非0都为异常

                    if(PublicUtil.isNotEmpty(resultCode) && "0".equals(resultCode)){
                        orderMainEntity.setChildStatus("1");
                        orderMainEntity.setUpdater(RequestUtil.getLoginUser().getUserCode());
                        orderMainEntity.setUpdateTime(new Date());
                        orderMainEntity.setStatus("01");
                        orderMainDao.update(orderMainEntity); // 更新服务单子状态
                        //2.更新服务单的实际服务商信息
                        Map<String, String> servicerMap = new HashMap<>();
                        servicerMap.put("orderNo", orderMainEntity.getOrderNo());
                        servicerMap.put("servicerId", servicerId);
                        Map<String, String> servicerParam = new HashMap<>();
                    	servicerParam.put("servicerId", servicerId);
                    	ServiceProviderEntity providerVo = serviceProviderService.findProviderByParam(servicerParam);
                    	String servicerName = providerVo.getServiceName();
                        servicerMap.put("servicerName", servicerName);
                        orderServiceProviderDao.updateServicer(servicerMap);
                        // 记录轨迹
                        saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单，成功", "01", new Date(), RequestUtil.getLoginUser());
                        result = "调用下游下单，成功";
                        flag = true;
                    } else {
                        orderMainEntity.setChildStatus("0");
                        orderMainEntity.setUpdater(RequestUtil.getLoginUser().getUserCode());
                        orderMainEntity.setUpdateTime(new Date());
                        orderMainEntity.setStatus("00");
                        orderMainDao.update(orderMainEntity); // 更新服务单子状态
                        result = PublicUtil.isNotEmpty(resultObj.get("message")) ? resultObj.get("message").toString() : null; // 错误信息，resultCod非0时必传
                        // 记录轨迹
                        saveTrack(orderMainEntity.getOrderNo(), "00", "调用下游下单，失败：" + result, "01", new Date(), RequestUtil.getLoginUser());
                        flag = false;
                    }
                } else {
                    //// 记录轨迹
                    saveTrack(orderMainEntity.getOrderNo(), "00", "下单失败，接口请求异常", "01", new Date(), RequestUtil.getLoginUser());
                    result = "下单接口请求异常";
                    flag = false;
                }
            } else {
                // 记录轨迹
                saveTrack(orderMainEntity.getOrderNo(), "00", "下单失败，仅允许对待处理和派发失败状态的服务单进行派单操作", "01", new Date(), RequestUtil.getLoginUser());
                result = "仅允许对待处理和派发失败状态的服务单进行派单操作";
                flag = false;
            }
        } else {
            LoginAuthDto loginUser = RequestUtil.getLoginUser();
            // 记录轨迹
            saveTrack("null", "00", "下单失败，服务单不存在", "01", new Date(), loginUser);
            result = "服务单不存在";
            flag = false;
        }
        resultMap.put("orderNo", orderMainEntity.getOrderNo());
        resultMap.put("dataId", dataId);
        resultMap.put("result", result);
        resultMap.put("flag", flag);
        return resultMap;
    }

    /**
     * @param dataId 服务单id
     * @param serverId 改派服务商id
     * @return
     * @description 改派
     * @author wkangle
     * @time 2021/09/08 0008 16:12
     * @exception/throws
     */
    @Override
    public Map<String, Object> changeAllotRescue(String dataId, String servicerId, String oldServicerId) {
    	Map<String, Object> responseMap = new HashMap<>();
        Map<String, Object> params = new HashMap<String, Object>();
        Map<String, Object> requestBodyMap = new HashMap<String, Object>();
        params.put("dataId", dataId);
        OrderMainEntity orderMainEntity = orderMainDao.getOneByParams(params);
        if(PublicUtil.isNotEmpty(orderMainEntity)){
            //if ("02".equals(orderMainEntity.getStatus()) || "03".equals(orderMainEntity.getStatus())){ // 02-已受理 03-已派单
            if (true){ // 2022年2月7日16:55:19 W 所有状态均可改派
                // 改派流程： 1-取消原下单请求，2-派单给选中的新服务商
            	List<ServiceProviderDataEntity> servicerUrlList = serviceProviderService.queryListByYwId(servicerId);
                List<ServiceProviderDataEntity> oldServicerUrlList = serviceProviderService.queryListByYwId(oldServicerId);
                String createRescue_url = ""; //下单接口
                String cancelRescue_url = ""; //取消接口
                for(ServiceProviderDataEntity data : servicerUrlList){
                	if(Constants.createRescue.equals(data.getUrlType())){
                		createRescue_url = data.getUrl();
                		break;
                	}
                }
                for(ServiceProviderDataEntity data : oldServicerUrlList){
                	if(Constants.cancelRescue.equals(data.getUrlType())){
                		cancelRescue_url = data.getUrl();
                		break;
                	}
                }
                if(PublicUtil.isEmpty(cancelRescue_url)){
                	responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "原服务商取消接口地址未找到");
                    return responseMap;
                }
                if(PublicUtil.isEmpty(createRescue_url)){
                	responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "改派服务商下单接口地址未找到");
                    return responseMap;
                }
                Map<String, String> servicerParam = new HashMap<>();
            	servicerParam.put("servicerId", servicerId);
            	ServiceProviderEntity providerVo = serviceProviderService.findProviderByParam(servicerParam);
            	String PD_PublicKey = providerVo.getPk();     //下单公钥
            	
            	requestBodyMap.put("orderNo", orderMainEntity.getOrderNo());
                requestBodyMap.put("cancelReason", "手工改派");
                String result = cancelService.cancelRescue(cancelRescue_url, requestBodyMap);
                
                LoginAuthDto loginUser = RequestUtil.getLoginUser();
                if (result != null) {
            		JSONObject resultObj = JSONObject.parseObject(result);
                    String resultCode = PublicUtil.isNotEmpty(resultObj.get("resultCode")) ? resultObj.get("resultCode").toString() : null;//0-正常、非0都为异常
                    if(PublicUtil.isNotEmpty(resultCode) && "0".equals(resultCode)){
                    	//改旧服务单的状态
                    	orderMainEntity.setStatus("09");
                        orderMainEntity.setVersion(orderMainEntity.getVersion() + 1);
                        orderMainEntity.setIfNewVersion(0); // 改为非最新版本
                        orderMainEntity.setUpdateTime(new Date());
                        orderMainEntity.setUpdater(loginUser.getUserCode());
                        orderMainDao.update(orderMainEntity);
                        //复制的新服务单主表
                        String newDataId = UUID.randomUUID().toString().replace("-", "");
                        orderMainEntity.setDataId(newDataId);
                        orderMainEntity.setStatus("01"); // 待处理
                        orderMainEntity.setUrgeCount(0); // 默认催单次数为0
                        orderMainEntity.setIsDalayed(0); // 延时单，默认0-非延时，1-延时
                        orderMainEntity.setVersion(1);
                        orderMainEntity.setIfNewVersion(1); // 最新版本
                        Date orderMainEntityNewTime = new Date();
                        orderMainEntity.setCreateTime(orderMainEntityNewTime);
                        orderMainEntity.setCreater(loginUser.getUserCode());
                        orderMainEntity.setUpdateTime(orderMainEntityNewTime);
                        orderMainEntity.setUpdater(loginUser.getUserCode());
                        orderMainDao.insert(orderMainEntity);
                        // 复制的新服务单保单信息
                        Map<String, Object> infoParams = new HashMap<String, Object>();
                        infoParams.put("orderNo", orderMainEntity.getOrderNo());
                        OrderPolicyEntity orderPolicyEntityNew = orderPolicyDao.getOneByParams(infoParams);
                        // 修改原数据为非最新版本
                        orderPolicyEntityNew.setVersion(orderPolicyEntityNew.getVersion() + 1);
                        orderPolicyEntityNew.setIfNewVersion(0);
                        orderPolicyEntityNew.setUpdater(loginUser.getUserCode());
                        orderPolicyEntityNew.setUpdateTime(new Date());
                        orderPolicyDao.update(orderPolicyEntityNew);
                        // 复制
                        orderPolicyEntityNew.setDataId(UUID.randomUUID().toString().replace("-", ""));
                        orderPolicyEntityNew.setVersion(1);
                        orderPolicyEntityNew.setIfNewVersion(1);
                        Date orderPolicyEntityNewTime = new Date();
                        orderPolicyEntityNew.setCreateTime(orderPolicyEntityNewTime);
                        orderPolicyEntityNew.setCreater(loginUser.getUserCode());
                        orderPolicyEntityNew.setUpdateTime(orderPolicyEntityNewTime);
                        orderPolicyEntityNew.setUpdater(loginUser.getUserCode());
                        orderPolicyDao.insert(orderPolicyEntityNew);
                        // 复制的新服务单客户信息
                        OrderCustomerEntity orderCustomerEntityNew = orderCustomerDao.getOneByParams(infoParams);
                        // 修改原数据为非最新版本
                        orderCustomerEntityNew.setVersion(orderCustomerEntityNew.getVersion() +  1);
                        orderCustomerEntityNew.setIfNewVersion(0);
                        orderCustomerEntityNew.setUpdater(loginUser.getUserCode());
                        orderCustomerEntityNew.setUpdateTime(new Date());
                        orderCustomerDao.update(orderCustomerEntityNew);
                        // 复制
                        orderCustomerEntityNew.setDataId(UUID.randomUUID().toString().replace("-", ""));
                        orderCustomerEntityNew.setVersion(1);
                        orderCustomerEntityNew.setIfNewVersion(1);
                        Date orderCustomerEntityNewTime = new Date();
                        orderCustomerEntityNew.setCreateTime(orderCustomerEntityNewTime);
                        orderCustomerEntityNew.setCreater(loginUser.getUserCode());
                        orderCustomerEntityNew.setUpdateTime(orderCustomerEntityNewTime);
                        orderCustomerEntityNew.setUpdater(loginUser.getUserCode());
                        orderCustomerDao.insert(orderCustomerEntityNew);
                        // 复制的新服务单待救援信息
                        OrderRescueEntity orderRescueEntityNew = orderRescueDao.getOneByParams(infoParams);
                        // 修改原数据为非最新版本
                        orderRescueEntityNew.setVersion(orderRescueEntityNew.getVersion() + 1);
                        orderRescueEntityNew.setIfNewVersion(0);
                        orderRescueEntityNew.setUpdater(loginUser.getUserCode());
                        orderRescueEntityNew.setUpdateTime(new Date());
                        orderRescueDao.update(orderRescueEntityNew);
                        // 复制
                        orderRescueEntityNew.setDataId(UUID.randomUUID().toString().replace("-", ""));
                        orderRescueEntityNew.setVersion(1);
                        orderRescueEntityNew.setIfNewVersion(1);
                        Date orderRescueEntityNewTime = new Date();
                        orderRescueEntityNew.setCreateTime(orderRescueEntityNewTime);
                        orderRescueEntityNew.setCreater(loginUser.getUserCode());
                        orderRescueEntityNew.setUpdateTime(orderRescueEntityNewTime);
                        orderRescueEntityNew.setUpdater(loginUser.getUserCode());
                        orderRescueDao.insert(orderRescueEntityNew);
                        // 复制的新服务单待救援信息
                        OrderServiceProviderEntity orderServiceProviderEntityNew = orderServiceProviderDao.getOneByParams(infoParams);
                        // 修改原数据为非最新版本
                        orderServiceProviderEntityNew.setVersion(orderServiceProviderEntityNew.getVersion() + 1);
                        orderServiceProviderEntityNew.setIfNewVersion(0);
                        orderServiceProviderEntityNew.setUpdater(loginUser.getUserCode());
                        orderServiceProviderEntityNew.setUpdateTime(new Date());
                        orderServiceProviderDao.update(orderServiceProviderEntityNew);
                        // 复制
                        orderServiceProviderEntityNew.setDataId(UUID.randomUUID().toString().replace("-", ""));
                        orderServiceProviderEntityNew.setServerId(servicerId);
                        orderServiceProviderEntityNew.setVersion(1);
                        orderServiceProviderEntityNew.setIfNewVersion(1);
                        Date orderServiceProviderEntityNewTime = new Date();
                        orderServiceProviderEntityNew.setCreateTime(orderServiceProviderEntityNewTime);
                        orderServiceProviderEntityNew.setCreater(loginUser.getUserCode());
                        orderServiceProviderEntityNew.setUpdateTime(orderServiceProviderEntityNewTime);
                        orderServiceProviderEntityNew.setUpdater(loginUser.getUserCode());
                        orderServiceProviderDao.insert(orderServiceProviderEntityNew);
                        // 复制的新服务单待救援信息
                        OrderServiceRescueEntity orderServiceRescueEntityNew = orderServiceRescueDao.getOneByParams(infoParams);
                        // 修改原数据为非最新版本
                        orderServiceRescueEntityNew.setVersion(orderServiceRescueEntityNew.getVersion() + 1);
                        orderServiceRescueEntityNew.setIfNewVersion(0);
                        orderServiceRescueEntityNew.setUpdater(loginUser.getUserCode());
                        orderServiceRescueEntityNew.setUpdateTime(new Date());
                        orderServiceRescueDao.update(orderServiceRescueEntityNew);
                        // 复制
                        orderServiceRescueEntityNew.setDataId(UUID.randomUUID().toString().replace("-", ""));
                        orderServiceRescueEntityNew.setVersion(1);
                        orderServiceRescueEntityNew.setIfNewVersion(1);
                        orderServiceRescueEntityNew.setCreateTime(new Date());
                        orderServiceRescueEntityNew.setCreater(loginUser.getUserCode());
                        orderServiceRescueEntityNew.setUpdateTime(new Date());
                        orderServiceRescueEntityNew.setUpdater(loginUser.getUserCode());
                        orderServiceRescueDao.insert(orderServiceRescueEntityNew);
                        //请求新服务商下单接口
                        Map<String, Object> allotRescue = this.allotRescue(newDataId, createRescue_url, servicerId, PD_PublicKey, false);
                        Boolean flag = Boolean.valueOf(allotRescue.get("flag").toString());
                        if (flag){
                        	responseMap.put("responseCode", "00");
                            responseMap.put("responseMsg", "派单成功");
                        }else{
                        	responseMap.put("responseCode", "01");
                            responseMap.put("responseMsg", "派单失败");
                        }
                    }else{
                    	saveTrack(orderMainEntity.getOrderNo(), "03", "手工改派失败，服务商取消接口请求失败", "09", new Date(), loginUser);
                        responseMap.put("responseCode", "00");
                        responseMap.put("responseMsg", "取消接口请求失败: " + (PublicUtil.isNotEmpty(resultObj.get("message")) ? resultObj.get("message").toString() : null)); // 错误信息，resultCod非0时必传
                        return responseMap;
                    }
            	}else{
            		saveTrack(orderMainEntity.getOrderNo(), "03", "改派---取消失败，取消接口请求异常", "09", new Date(), loginUser);
                    responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "取消接口请求异常");
                    return responseMap;
            	}
                
            } 
            /*else {
                // 记录轨迹
                // 改派备注；已派单
                saveTrack(orderMainEntity.getOrderNo(), "04", "改派失败，仅可对已受理、已派单的服务单进行改派操作", "04", new Date(), RequestUtil.getLoginUser());
                responseMap.put("responseCode", "00");
                responseMap.put("responseMsg", "仅可对已受理、已派单的服务单进行改派操作");
            }*/
        } else {
            responseMap.put("responseCode", "00");
            responseMap.put("responseMsg", "服务单不存在");
        }
        return responseMap;
    }

    /**
     * @description 根据条件保存轨迹
     * @param orderNo 服务单号
     * @param trackType 轨迹类型
     * @param trackDesc 轨迹描述
     * @param status 状态
     * @param currentDate 当前时间
     * @param loginUser 当前登录对象
     * @return
     * @author wkangle
     * @time 2021/09/27 0027 16:39
     * @exception/throws
     */
    private void saveTrack(String orderNo, String trackType, String trackDesc, String status, Date currentDate, LoginAuthDto loginUser){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);

        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(loginUser.getUserCode());
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(loginUser.getUserCode());
        orderTrackDao.insert(orderTrackEntity);
    }
    
    /**
	*
	* @author WANGCONG
	* 2021年10月21日下午5:25:32
	* @desc 页面操作---拦截取消Version-2.0
	*/
    /**
     * 规则：          
               页面操作拦截取消：
		服务单完成、服务取消、派发失败不能操作拦截取消，弹框提示"XXX不符合取消要求"
		除此之外，调对应下游的取消接口和上游取消通知接口；
	   上游取消：
		服务单不是派发失败状态，调对应下游取消接口；
		是派发失败状态，本地更新状态为服务取消。返回"取消成功"。
     * @throws Exception 
     */
    @Override
    public Map<String, Object> cancelRescue(String dataId, String cancelReason, String servicerId, String cancelType, String serviceAmount,
    		String cancelCode, String totalDistance, String usedDistance) throws Exception {
        Map<String, Object> responseMap = new HashMap<>();
        Map<String, Object> requestBodyMap = new HashMap<String, Object>();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("dataId", dataId);
        OrderMainEntity orderMainEntity = orderMainDao.getOneByParams(params);
        if (PublicUtil.isNotEmpty(orderMainEntity)){
        	String orderStatus = orderMainEntity.getStatus();
        	String sourceName = orderMainEntity.getSourceName();//渠道来源：00-自营、01-阳光
        	String ownerOrderNo = orderMainEntity.getOwnerOrderNo();
        	String orderNo = orderMainEntity.getOrderNo();
        	//调用上游取消通知接口
        	CancelNoticeModel cancelNoticeModel = new CancelNoticeModel();
        	cancelNoticeModel.setSourceName(sourceName);
            //救援单号
            cancelNoticeModel.setOwnerOrderNo(ownerOrderNo);
            String salvationStatus = "";
            int amount = Integer.parseInt(serviceAmount);
            if(amount>0){//产生空驶费
            	salvationStatus = "CANCEL_COST";//工单取消_产生空驶费
            }else{
            	if(orderStatus.equals("01")||orderStatus.equals("02")){
                	salvationStatus = "CANCEL_BEFORE_DISPATCHING";//派单前取消服务
                }else{
                	salvationStatus = "CANCEL_AFTER_DISPATCHING";//派单后取消服务
                }
            }
            //救援状态
            cancelNoticeModel.setSalvationStatus(salvationStatus);
            //实际救援服务金额
            cancelNoticeModel.setServiceAmount(serviceAmount);
            //取消备注
            cancelNoticeModel.setCancelReason(cancelReason);
            String cancelTime = DateUtil.getCurrentDate("yyyy-MM-dd HH:mm:ss");
            String createTime = DateUtil.getStrDate(orderMainEntity.getCreateTime(), "yyyy-MM-dd HH:mm:ss");
            int elapsedTime= DateUtil.getIntervalSecond(createTime, cancelTime);
            //取消时间：yyyy-MM-dd HH:mm:ss
            cancelNoticeModel.setCancelTime(cancelTime);
            
			Map<String, Object> dictParams = new HashMap<>();
			dictParams.put("typeCode", "cancelStatus");
			dictParams.put("code", cancelCode);
			DictCodeEntity dictCodeEntity = dictCodeDao.getOneByParams(dictParams);
            //取消状态说明
            cancelNoticeModel.setCancelMsg(dictCodeEntity.getValue());
            //取消状态代码
            cancelNoticeModel.setCancelCode(cancelCode);
            //预计总行程距离（单位：m）
            cancelNoticeModel.setTotalDistance(totalDistance);
            //已行驶距离（单位：m）
            cancelNoticeModel.setUsedDistance(usedDistance);
            //已用时间，保司请求下单接口的请求时间至取消发起时间点（单位：秒）
            cancelNoticeModel.setElapsedTime(String.valueOf(elapsedTime));
            cancelNoticeModel.setUpdater("服务商");
            cancelNoticeModel.setCreater("服务商");
            
            if (!"08".equals(orderStatus) && !"09".equals(orderStatus)&& !"00".equals(orderStatus)&& !"10".equals(orderStatus)&& !"11".equals(orderStatus) ){ // 08-已完成 09-服务取消 00-派发失败
            	//本地记录操作轨迹，更新服务单状态
            	LoginAuthDto loginUser = RequestUtil.getLoginUser();
            	//调用下游接口，本地状态不变更
        		Map<String, String> servicerParam = new HashMap<>();
            	servicerParam.put("servicerId", servicerId);
            	List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
            	String cancelUrl = "";
            	for(int i=0; i<urlList.size(); i++){
            		if(Constants.cancelRescue.equals(urlList.get(i).getUrlType())){
            			cancelUrl = urlList.get(i).getUrl();
            			break;
            		}
            	}
            	if(PublicUtil.isEmpty(cancelUrl)){
            		saveTrack(orderMainEntity.getOrderNo(), "03", "取消失败，未找到服务商取消接口地址", "09", new Date(), loginUser);
            		responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "取消失败，未找到服务商取消接口地址");
                    return responseMap;
            	}
            	requestBodyMap.put("orderNo", orderMainEntity.getOrderNo());
                requestBodyMap.put("cancelReason", cancelReason);
                
                //TODO 取消默认成功
            	String result = cancelService.cancelRescue(cancelUrl, requestBodyMap);
//            	String result = "{\"resultCode\":\"0\",\"message\":\"成功\"}";
            	if (result != null) {
            		JSONObject resultObj = JSONObject.parseObject(result);
                    String resultCode = PublicUtil.isNotEmpty(resultObj.get("resultCode")) ? resultObj.get("resultCode").toString() : null; // 0：正常；非0都为异常
                    if(PublicUtil.isNotEmpty(resultCode) && "0".equals(resultCode)){
                    	// 下游取消成功，更新车服平台服务单状态为服务取消
                    	orderMainDao.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName);
                    	saveTrack(orderMainEntity.getOrderNo(), "03", cancelReason, "09", new Date(), loginUser);
                        responseMap.put("responseCode", "00");
                        responseMap.put("responseMsg", "取消成功");
                        
                        OrderMainEntity orderMain = new OrderMainEntity();
                        orderMain.setDataId(dataId);
                        if(amount>0){//取消有费用
                        	orderMain.setEmptyAmount(serviceAmount);
                        	orderMain.setVainDistance(usedDistance);
                    		orderMain.setStatus("10");
                    	}else{//取消无费用
                    		orderMain.setStatus("11");
                    	}
                    	orderMain.setCancelChannel("3");//车服取消
                        orderMain.setUpdateTime(new Date());
                        orderMainDao.update(orderMain);
                        
//                      if(!"00".equals(sourceName)){
                        if("01".equals(sourceName)){ //00-自营、01-阳光、02-中华，只有阳光的单子对上游进行回写
                        	String cancelNoticeResult = cancelNoticeService.cancelNotice(cancelNoticeModel);
                            logger.info("服务单取消接口请求结果--"+cancelNoticeResult);
                        }else{//自营服务单 需要插入 取消有/无非费用的轨迹
                        	cancelNoticeService.insertCancelTrack(cancelNoticeModel,"取消备注："+cancelReason);
                        }
                        return responseMap;
                    }else{
                    	saveTrack(orderMainEntity.getOrderNo(), "03", "取消失败，取消接口请求失败", "09", new Date(), loginUser);
                        responseMap.put("responseCode", "00");
                        responseMap.put("responseMsg", "取消接口请求失败: " + (PublicUtil.isNotEmpty(resultObj.get("message")) ? resultObj.get("message").toString() : null)); // 错误信息，resultCod非0时必传
                        return responseMap;
                    }
            	}else{
            		saveTrack(orderMainEntity.getOrderNo(), "03", "取消失败，取消接口请求异常", "09", new Date(), loginUser);
                    responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "取消接口请求异常");
                    return responseMap;
            	}
            } else {
                LoginAuthDto loginUser = RequestUtil.getLoginUser();
                if("08".equals(orderStatus) || "09".equals(orderStatus)|| "00".equals(orderStatus)){
                	// 记录轨迹---取消备注；服务取消
                    saveTrack(orderMainEntity.getOrderNo(), "03", "取消失败，派发失败、已完成或服务取消状态的服务单不允许拦截取消", "09", new Date(), loginUser);
                    responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "派发失败、已完成或服务取消状态的服务单不允许拦截取消");
                }else if("10".equals(orderStatus)){
                	// 记录轨迹---取消有费用
                	saveTrack(orderMainEntity.getOrderNo(), "03", "服务单："+orderNo+"状态为取消有费用，不可操作取消", "09", new Date(), loginUser);
                    responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "服务单："+orderNo+"状态为取消有费用，不可操作取消");
                }else {
                	// 记录轨迹---取消无费用
                    saveTrack(orderMainEntity.getOrderNo(), "03", "服务单："+orderNo+"状态为取消无费用，不可操作取消", "09", new Date(), loginUser);
                    responseMap.put("responseCode", "01");
                    responseMap.put("responseMsg", "服务单："+orderNo+"状态为取消无费用，不可操作取消");
                }
                return responseMap;
            }
        } else {
            LoginAuthDto loginUser = RequestUtil.getLoginUser();
            // 记录轨迹---取消备注；服务取消
            saveTrack(orderMainEntity.getOrderNo(), "03", "取消失败，服务单不存在", "09", new Date(), loginUser);
            responseMap.put("responseCode", "01");
            responseMap.put("responseMsg", "服务单不存在");
            return responseMap;
        }
    }
    
}
